﻿#include <cstdint>
#include "PlatformProperty.h"
#include "SignalManager.h"
#include "ap/signal_id.h"
#include <iostream>
#include <chrono>
#include <thread>
#include <OpHmiSeatClimaStructUtil.h>

// 主驾超时反馈
#define HVAC_SEAT_TEMPERATURE_MSG_1 1001
// 副驾超时反馈
#define HVAC_SEAT_TEMPERATURE_MSG_2 1002
// 二排左超时反馈
#define HVAC_SEAT_TEMPERATURE_MSG_3 1003
// 二排右超时反馈
#define HVAC_SEAT_TEMPERATURE_MSG_4 1004
// 副驾关闭加热、关闭档位
#define HVAC_SEAT_TEMPERATURE_PASS_NB 1005
// 二排左关闭加热、关闭档位
#define HVAC_SEAT_TEMPERATURE_SEC_LE_NB 1007
// 二排右关闭加热、关闭档位
#define HVAC_SEAT_TEMPERATURE_SEC_RI_NB 1009

#define HVAC_DELAY 3 * 1000

#define HEAT_TIME 59

#define DID_DRVR_SEAT_HEATG_LVL_STS "DrvrSeatHeatgLvlSts "
#define DID_DRVR_AMB_T_RAW_AMB_T_VAL "AmbTRawAmbTValDriver "
#define DID_DRVR_AUTO_SEAT_HEAT_FLAG "AutoSeatHeatFlagDriver "
#define DID_PASS_SEAT_HEATG_LVL_STS "PassSeatHeatgLvlSts "
#define DID_PASS_AMB_T_RAW_AMB_T_VAL "AmbTRawAmbTValPass "
#define DID_PASS_AUTO_SEAT_HEAT_FLAG "AutoSeatHeatFlagPass "

namespace ecarx::vhal::core::property::impl { class VehiclePropertyHVAC_SEAT_TEMPERATURE; }

sdb::UsgModSts1 lastUsgMode = sdb::UsgModSts1::UsgModAbdnd;

// 副驾无人乘坐时间计时
std::chrono::time_point<std::chrono::steady_clock> mPassStart, mPassEnd;
// 第二排左边无人乘坐时间计时
std::chrono::time_point<std::chrono::steady_clock> mSecLeStart, mSecLeEnd;
// 第二排右边无人乘坐时间计时
std::chrono::time_point<std::chrono::steady_clock> mSecRiStart, mSecRiEnd;

// 是否座椅上无人计时中
bool mIsPassCounting = false;
bool mIsSecLeCounting = false;
bool mIsSecRiCounting = false;

// 是否等待反馈中
static bool mIsWaitingMsg1 = false;
static bool mIsWaitingMsg2 = false;
static bool mIsWaitingMsg3 = false;
static bool mIsWaitingMsg4 = false;

// 设置请求值缓存
int32_t g_heatDrvrReqValue = NONE;
int32_t g_heatPassReqValue = NONE;
int32_t g_heatSecLeReqValue = NONE;
int32_t g_heatSecRiReqValue = NONE;

bool hasSendTmr = false;

static void removeMessage(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, uint32_t msgId);

static void sendMessage(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, uint32_t msgId, int32_t value);

static bool isWaiting(int32_t msgId) {
    switch (msgId)
    {
    case HVAC_SEAT_TEMPERATURE_MSG_1:
        return mIsWaitingMsg1;
    case HVAC_SEAT_TEMPERATURE_MSG_2:
        return mIsWaitingMsg2;
    case HVAC_SEAT_TEMPERATURE_MSG_3:
        return mIsWaitingMsg3;
    case HVAC_SEAT_TEMPERATURE_MSG_4:
        return mIsWaitingMsg4;
    }
    return false;
}

static void setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1 onOff1) {
    if (onOff1 == sdb::OnOff1::Off) {
        VHALOG.d("HVAC_SEAT_TEMPERATURE setCB_VFC_SeatClimaForHmiCenPDC OFF");
        SIGNAL.setCB_VFC_SeatClimaForHmiCenPDC(onOff1);
    } else if (SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc)) {
        VHALOG.d("HVAC_SEAT_TEMPERATURE setCB_VFC_SeatClimaForHmiCenPDC ON");
        SIGNAL.setCB_VFC_SeatClimaForHmiCenPDC(onOff1);
    }
}

VehicleAreaSeat getDrvrArea() {
    return (isLeftRudder() ? VehicleAreaSeat::ROW_1_LEFT : VehicleAreaSeat::ROW_1_RIGHT);
}

VehicleAreaSeat getPassArea() {
    return (isLeftRudder() ? VehicleAreaSeat::ROW_1_RIGHT : VehicleAreaSeat::ROW_1_LEFT);
}

void sendSeatHeatTmr() {
    if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModAbdnd)) {
        VHALOG.d("HVAC_SEAT_TEMPERATURE setCB_VFC_MmedbtnifClimate On");
        SIGNAL.setCB_VFC_MmedbtnifClimate(sdb::OnOff1::On);
    }
    OpHmiSeatClimaTmr_SetRequestNoReturn climateTmrValue;
    climateTmrValue.hmiSeatClimaTmrHmiSeatHeatgFirstLeTmr = HEAT_TIME;
    climateTmrValue.hmiSeatClimaTmrHmiSeatHeatgFirstRiTmr = HEAT_TIME;
    climateTmrValue.hmiSeatClimaTmrHmiSeatHeatgSecLeTmr = HEAT_TIME;
    climateTmrValue.hmiSeatClimaTmrHmiSeatHeatgSecRiTmr = HEAT_TIME;
    climateTmrValue.hmiSeatClimaTmrHmiSeatVentnFirstLeTmr = HEAT_TIME;
    climateTmrValue.hmiSeatClimaTmrHmiSeatVentnFirstRiTmr = HEAT_TIME;
    climateTmrValue.hmiSeatClimaTmrHmiSeatVentnSecLeTmr = HEAT_TIME;
    climateTmrValue.hmiSeatClimaTmrHmiSeatVentnSecRiTmr = HEAT_TIME;
    SIGNAL.setHmiSeatClimaTmr(climateTmrValue);
}

void setSeatHeat(int32_t drvrlvl, int32_t passlvl , int32_t secLelvl, int32_t secRilvl, int32_t ventDrvrlvl, int32_t ventPasslvl , int32_t ventSecLelvl, int32_t ventSecRilvl) {
    VHALOG.d("HVAC_SEAT_TEMPERATURE  setSeatHeat,drvrlvl:%d, passlvl: %d, secLelvl: %d, secRilvl: %d, ventDrvrlvl:%d, ventPasslvl: %d, ventSecLelvl: %d, ventSecRilvl: %d",
            drvrlvl, passlvl, secLelvl, secRilvl, ventDrvrlvl, ventPasslvl, ventSecLelvl, ventSecRilvl);
    OpHmiSeatClima_SetRequestNoReturn climaValue = getCurrOpHmiSeatClima();
    if (drvrlvl != NONE) {
        g_heatDrvrReqValue = drvrlvl;
        if (isLeftRudder()) {
            climaValue.hmiSeatClimaHmiSeatHeatgForRowFirstLe = (uint8_t)mappingValue(drvrlvl, sdb::SeatClimaLvl::Off);
        } else {
            climaValue.hmiSeatClimaHmiSeatHeatgForRowFirstRi = (uint8_t)mappingValue(drvrlvl, sdb::SeatClimaLvl::Off);
        }
    }
    if (passlvl != NONE) {
        g_heatPassReqValue = passlvl;
        if (isLeftRudder()) {
            climaValue.hmiSeatClimaHmiSeatHeatgForRowFirstRi = (uint8_t)mappingValue(passlvl, sdb::SeatClimaLvl::Off);
        } else {
            climaValue.hmiSeatClimaHmiSeatHeatgForRowFirstLe = (uint8_t)mappingValue(passlvl, sdb::SeatClimaLvl::Off);
        }
    }
    if (secLelvl != NONE) {
        g_heatSecLeReqValue = secLelvl;
        climaValue.hmiSeatClimaHmiSeatHeatgForRowSecLe = (uint8_t)mappingValue(secLelvl, sdb::SeatClimaLvl::Off);
    }
    if (secRilvl != NONE) {
        g_heatSecRiReqValue = secRilvl;
        climaValue.hmiSeatClimaHmiSeatHeatgForRowSecRi = (uint8_t)mappingValue(secRilvl, sdb::SeatClimaLvl::Off);
    }

    if (ventDrvrlvl != NONE) {
        g_ventDrvrReqValue = ventDrvrlvl;
        if (isLeftRudder()) {
            climaValue.hmiSeatClimaHmiSeatVentnForRowFirstLe = (uint8_t)mappingValue(ventDrvrlvl, sdb::SeatClimaLvl::Off);
        } else {
            climaValue.hmiSeatClimaHmiSeatVentnForRowFirstRi = (uint8_t)mappingValue(ventDrvrlvl, sdb::SeatClimaLvl::Off);
        }
    }
    if (ventPasslvl != NONE) {
        g_ventPassReqValue = ventPasslvl;
        if (isLeftRudder()) {
            climaValue.hmiSeatClimaHmiSeatVentnForRowFirstRi = (uint8_t)mappingValue(ventPasslvl, sdb::SeatClimaLvl::Off);
        } else {
            climaValue.hmiSeatClimaHmiSeatVentnForRowFirstLe = (uint8_t)mappingValue(ventPasslvl, sdb::SeatClimaLvl::Off);
        }
    }
    if (ventSecLelvl != NONE) {
        g_ventSecLeReqValue = ventSecLelvl;
        climaValue.hmiSeatClimaHmiSeatVentnForRowSecLe = (uint8_t)mappingValue(ventSecLelvl, sdb::SeatClimaLvl::Off);
    }
    if (ventSecRilvl != NONE) {
        g_ventSecRiReqValue = ventSecRilvl;
        climaValue.hmiSeatClimaHmiSeatVentnForRowSecRi = (uint8_t)mappingValue(ventSecRilvl, sdb::SeatClimaLvl::Off);
    }
    SIGNAL.setHmiSeatClima(climaValue);
}

// 设置主驾座椅档位
void setDriverSeatHeat(int32_t drvrlvl) {
    setSeatHeat(drvrlvl, NONE, NONE, NONE, NONE, NONE, NONE, NONE);
}

// 设置副驾座椅档位
void setPassSeatHeat(int32_t passlvl) {
    setSeatHeat(NONE, passlvl, NONE, NONE, NONE, NONE, NONE, NONE);
}

// 设置第二排左边座椅档位
void setSecLeSeatHeat(int32_t secLelvl) {
    setSeatHeat(NONE, NONE, secLelvl, NONE, NONE, NONE, NONE, NONE);
}

// 设置第二排右边座椅档位
void setSecRiSeatHeat(int32_t secRilvl) {
    setSeatHeat(NONE, NONE, NONE, secRilvl, NONE, NONE, NONE, NONE);
}

PropertyStatus getSeatHeatDriverStatus() {
    auto chrSt = SIGNAL.getOnBdChrgrSt();
    if (SIGNAL.carConfigIs(SignalRX::carconfig180, sdb::CarConfig180::_02, sdb::CarConfig180::_80)) {
        if (SIGNAL.getDrvrSeatHeatgAvlSts() == sdb::StsFd::Functionallimit) {
            return PropertyStatus::NotActive;
        }
        if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_01, sdb::CarConfig13::_02, sdb::CarConfig13::_80)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
                && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg)) {
            return PropertyStatus::Active;
        } else if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_03)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)) {
            if (SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg)) {
                return PropertyStatus::Active;
            } else if (SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc)
                    && chrSt == sdb::ChrgrSts1::Chrgn) {
                return PropertyStatus::Active;
            }
        } else if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
                && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg, sdb::UsgModSts1::UsgModCnvinc, sdb::UsgModSts1::UsgModActv)) {
            return PropertyStatus::Active;
        }
        return PropertyStatus::NotActive;
    }
    return PropertyStatus::NotAvailable;
}

PropertyStatus getSeatHeatPassStatus() {
    auto chrSt = SIGNAL.getOnBdChrgrSt();
    if (SIGNAL.carConfigIs(SignalRX::carconfig180, sdb::CarConfig180::_02)) {
        if (SIGNAL.getPassSeatHeatgAvlSts() == sdb::StsFd::Functionallimit) {
            return PropertyStatus::NotActive;
        }
        if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_01, sdb::CarConfig13::_02, sdb::CarConfig13::_80)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
                && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg)) {
            return PropertyStatus::Active;
        } else if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_03)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)) {
            if (SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg)) {
                return PropertyStatus::Active;
            } else if (SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc)
                    && chrSt == sdb::ChrgrSts1::Chrgn) {
                return PropertyStatus::Active;
            }
        } else if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
                && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg, sdb::UsgModSts1::UsgModCnvinc, sdb::UsgModSts1::UsgModActv)) {
            return PropertyStatus::Active;
        }
        return PropertyStatus::NotActive;
    }
    return PropertyStatus::NotAvailable;
}

PropertyStatus getSeatHeatSecLeStatus() {
    auto chrSt = SIGNAL.getOnBdChrgrSt();
    if (SIGNAL.carConfigIs(SignalRX::carconfig181, sdb::CarConfig181::_02)) {
        if (SIGNAL.getSeatHeatgAvlStsRowSecLe() == sdb::StsFd::Functionallimit) {
            return PropertyStatus::NotActive;
        }
        if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_01, sdb::CarConfig13::_02, sdb::CarConfig13::_80)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
                && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg)) {
            return PropertyStatus::Active;
        } else if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_03)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)) {
            if (SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg)) {
                return PropertyStatus::Active;
            } else if (SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc)
                    && chrSt == sdb::ChrgrSts1::Chrgn) {
                return PropertyStatus::Active;
            }
        } else if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
                && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg, sdb::UsgModSts1::UsgModCnvinc, sdb::UsgModSts1::UsgModActv)) {
            return PropertyStatus::Active;
        }
        return PropertyStatus::NotActive;
    }
    return PropertyStatus::NotAvailable;
}

PropertyStatus getSeatHeatSecRiStatus() {
    auto chrSt = SIGNAL.getOnBdChrgrSt();
    if (SIGNAL.carConfigIs(SignalRX::carconfig181, sdb::CarConfig181::_02)) {
        if (SIGNAL.getSeatHeatgAvlStsRowSecRi() == sdb::StsFd::Functionallimit) {
            return PropertyStatus::NotActive;
        }
        if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_01, sdb::CarConfig13::_02, sdb::CarConfig13::_80)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
                && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg)) {
            return PropertyStatus::Active;
        } else if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_03)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)) {
            if (SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg)) {
                return PropertyStatus::Active;
            } else if (SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc)
                    && chrSt == sdb::ChrgrSts1::Chrgn) {
                return PropertyStatus::Active;
            }
        } else if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04)
                && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
                && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg, sdb::UsgModSts1::UsgModCnvinc, sdb::UsgModSts1::UsgModActv)) {
            return PropertyStatus::Active;
        }
        return PropertyStatus::NotActive;
    }
    return PropertyStatus::NotAvailable;
}

static PropertyStatus getSeatVentDriverStatus() {
    auto chrSt = SIGNAL.getOnBdChrgrSt();
    if (SIGNAL.carConfigIs(SignalRX::carconfig179, sdb::CarConfig179::_02,
                            sdb::CarConfig179::_03, sdb::CarConfig179::_80,
                            sdb::CarConfig179::_81, sdb::CarConfig179::_82,
                            sdb::CarConfig179::_83, sdb::CarConfig179::_84)) {
        if (SIGNAL.getDrvrSeatVentAvlSts() == sdb::StsFd::Functionallimit) {
            return PropertyStatus::NotActive;
        }
        if ((SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_01, sdb::CarConfig13::_02, sdb::CarConfig13::_80)) &&
            SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg) &&
            SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm,
                                sdb::CarModSts1::CarModDyno)) {
            return PropertyStatus::Active;
        }
        else if(SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_03)
            && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno))
        {
            if(SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg))
            {
                return PropertyStatus::Active;
            }
            else if(SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc) && chrSt == sdb::ChrgrSts1::Chrgn)
            {
                return PropertyStatus::Active;
            }
        }
        else if(SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04) && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
            && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg, sdb::UsgModSts1::UsgModCnvinc, sdb::UsgModSts1::UsgModActv))
        {
            return PropertyStatus::Active;
        }

        return PropertyStatus::NotActive;
    }
    return PropertyStatus::NotAvailable;
}

static PropertyStatus getSeatVentPassStatus() {
    auto chrSt = SIGNAL.getOnBdChrgrSt();
    if (SIGNAL.carConfigIs(SignalRX::carconfig179, sdb::CarConfig179::_02,
                            sdb::CarConfig179::_03, sdb::CarConfig179::_80,
                            sdb::CarConfig179::_81, sdb::CarConfig179::_82,
                            sdb::CarConfig179::_83, sdb::CarConfig179::_84)) {
        if (SIGNAL.getDrvrSeatVentAvlSts() == sdb::StsFd::Functionallimit) {
            return PropertyStatus::NotActive;
        }
        if ((SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_01, sdb::CarConfig13::_02, sdb::CarConfig13::_80)) &&
            SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg) &&
            SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm,
                                sdb::CarModSts1::CarModDyno)) {
            return PropertyStatus::Active;
        }
        else if(SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_03)
            && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno))
        {
            if(SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg))
            {
                return PropertyStatus::Active;
            }
            else if(SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc) && chrSt == sdb::ChrgrSts1::Chrgn)
            {
                return PropertyStatus::Active;
            }
        }
        else if(SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04) && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
            && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg, sdb::UsgModSts1::UsgModCnvinc, sdb::UsgModSts1::UsgModActv))
        {
            return PropertyStatus::Active;
        }

        return PropertyStatus::NotActive;
    }
    return PropertyStatus::NotAvailable;
}

static PropertyStatus getSeatVentSecLeStatus() {
    auto chrSt = SIGNAL.getOnBdChrgrSt();
    if (SIGNAL.carConfigIs(SignalRX::carconfig189, sdb::CarConfig189::_02)) {
        if (SIGNAL.getSeatVentAvlStsRowSecLe() == sdb::StsFd::Functionallimit) {
            return PropertyStatus::NotActive;
        }

        if((SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_01, sdb::CarConfig13::_02, sdb::CarConfig13::_80)) &&
            SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg) &&
            SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm,
                                sdb::CarModSts1::CarModDyno)) {
            return PropertyStatus::Active;
        }
        else if(SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_03)
            && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno))
        {
            if(SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg))
            {
                return PropertyStatus::Active;
            }
            else if(SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc) && chrSt == sdb::ChrgrSts1::Chrgn)
            {
                return PropertyStatus::Active;
            }
        }
        else if(SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04) && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
            && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg, sdb::UsgModSts1::UsgModCnvinc, sdb::UsgModSts1::UsgModActv))
        {
            return PropertyStatus::Active;
        }

        return PropertyStatus::NotActive;
    }
    return PropertyStatus::NotAvailable;
}

static PropertyStatus getSeatVentSecRiStatus() {
    auto chrSt = SIGNAL.getOnBdChrgrSt();
    if(SIGNAL.carConfigIs(SignalRX::carconfig189, sdb::CarConfig189::_02))
    {
        if (SIGNAL.getSeatVentAvlStsRowSecRi() == sdb::StsFd::Functionallimit) {
            return PropertyStatus::NotActive;
        }

        if((SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_01, sdb::CarConfig13::_02, sdb::CarConfig13::_80)) &&
            SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg) &&
            SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm,
                                sdb::CarModSts1::CarModDyno)) {
            return PropertyStatus::Active;
        }
        else if(SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_03)
            && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno))
        {
            if(SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg))
            {
                return PropertyStatus::Active;
            }
            else if(SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModCnvinc) && chrSt == sdb::ChrgrSts1::Chrgn)
            {
                return PropertyStatus::Active;
            }
        }
        else if(SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04) && SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm, sdb::CarModSts1::CarModDyno)
            && SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModDrvg, sdb::UsgModSts1::UsgModCnvinc, sdb::UsgModSts1::UsgModActv))
        {
            return PropertyStatus::Active;
        }

        return PropertyStatus::NotActive;
    }
    return PropertyStatus::NotAvailable;
}

void offSeatClimaAll(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, bool offDriverV,
        bool offPassV, bool offSecLeV, bool offSecRiV, bool offDriverH, bool offPassH, bool offSecLeH, bool offSecRiH);

void checkCountdown(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, VehicleAreaSeat area, bool &isCounting,
        std::chrono::time_point<std::chrono::steady_clock> &start, std::chrono::time_point<std::chrono::steady_clock> &end);

void clearCountdown(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, VehicleAreaSeat area);

PropertyStatus withStatusBySignalsDrvr(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr);

PropertyStatus withStatusBySignalsPass(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr);

int32_t withValueBySignalsDrvr(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, const int32_t& last);

int32_t withValueBySignalsPass(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, const int32_t& last);

void onSetPropertyDrvr(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, const int32_t& value);

void onSetPropertyPass(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, const int32_t& value);

//[SW_FC_003_027] 座椅加热功能SeatHeater---档位设定
SYSTEM_READ_WRITE_PROPERTY(HVAC_SEAT_TEMPERATURE, int32_t) {
    builder.area(VehicleAreaSeat::ROW_1_LEFT)
        .initValue([]() { return SEAT_CLIMA_OFF; })
        .withStatusBySignals(
            [this]([[maybe_unused]] const PropertyStatus& lastStatus) {
                if (isLeftRudder()) {
                    return withStatusBySignalsDrvr(this);
                }
                return withStatusBySignalsPass(this);
            },SignalRX::carconfig180,
            SignalRX::carconfig13,
            SignalRX::OnBdChrgrSt,
            SignalRX::VehModMngtGlbSafe1UsgModSts,
            SignalRX::VehModMngtGlbSafe1CarModSts1,
            SignalRX::RowFrstPassODSSts,
            SignalRX::PassSeatHeatgLvlSts,
            SignalRX::carconfig179,
            SignalRX::carconfig189,
            SignalRX::DrvrSeatHeatgAvlSts,
            SignalRX::PassSeatHeatgAvlSts,
            SignalRX::SeatHeatgAvlStsRowSecLe,
            SignalRX::SeatHeatgAvlStsRowSecRi,
            SignalRX::DrvrSeatVentAvlSts,
            SignalRX::PassSeatVentAvlSts,
            SignalRX::SeatVentAvlStsRowSecLe,
            SignalRX::SeatVentAvlStsRowSecRi)
        .withValueBySignals(
            [this]([[maybe_unused]] const int32_t& last) {
                if (isLeftRudder()) {
                    return withValueBySignalsDrvr(this, last);
                }
                return withValueBySignalsPass(this, last);
            }, SignalRX::DrvrSeatHeatgLvlSts,
            SignalRX::PassSeatHeatgLvlSts)
        .onSetProperty([this](const int32_t& value) {
            if (isLeftRudder()) {
                onSetPropertyDrvr(this, value);
            } else {
                onSetPropertyPass(this, value);
            }
        })
        .onMsgEvent(HVAC_SEAT_TEMPERATURE_MSG_1, [this]() {
            removeMessage(this, HVAC_SEAT_TEMPERATURE_MSG_1);
            // 3s后根据反馈信号更新
            setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::Off);

            auto sdbValue = mappingValue(SIGNAL.getDrvrSeatHeatgLvlSts(), SEAT_CLIMA_OFF);

            VHALOG.d("halOnMsgEvent HVAC_SEAT_TEMPERATURE HVAC_SEAT_TEMPERATURE_MSG_1: g_heatDrvrReqValue:%d, sdbValue: %d", g_heatDrvrReqValue, sdbValue);
            if (g_heatDrvrReqValue != sdbValue) {
                g_heatDrvrReqValue = sdbValue;
                setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::On);
                setDriverSeatHeat(g_heatDrvrReqValue);
            }
            setValue(toInt(getDrvrArea()), g_heatDrvrReqValue, false);
        })
        .area(VehicleAreaSeat::ROW_1_RIGHT)
        .initValue([]() { return SEAT_CLIMA_OFF; })
        .withStatusBySignals([this]([[maybe_unused]] const PropertyStatus& lastStatus) {
            if (isLeftRudder()) {
                return withStatusBySignalsPass(this);
            }
            return withStatusBySignalsDrvr(this);
        },SignalRX::carconfig180,
        SignalRX::carconfig13,
        SignalRX::OnBdChrgrSt,
        SignalRX::VehModMngtGlbSafe1UsgModSts,
        SignalRX::VehModMngtGlbSafe1CarModSts1,
        SignalRX::RowFrstPassODSSts,
        SignalRX::PassSeatHeatgLvlSts,
        SignalRX::carconfig179,
        SignalRX::carconfig189,
        SignalRX::DrvrSeatHeatgAvlSts,
        SignalRX::PassSeatHeatgAvlSts,
        SignalRX::SeatHeatgAvlStsRowSecLe,
        SignalRX::SeatHeatgAvlStsRowSecRi,
        SignalRX::DrvrSeatVentAvlSts,
        SignalRX::PassSeatVentAvlSts,
        SignalRX::SeatVentAvlStsRowSecLe,
        SignalRX::SeatVentAvlStsRowSecRi)
        .withValueBySignals([this]([[maybe_unused]] const int32_t& last) {
            if (isLeftRudder()) {
                return withValueBySignalsPass(this, last);
            }
            return withValueBySignalsDrvr(this, last);
        }, SignalRX::DrvrSeatHeatgLvlSts,
        SignalRX::PassSeatHeatgLvlSts)
        .onSetProperty([this](const int32_t& value) {
            if (isLeftRudder()) {
                onSetPropertyPass(this, value);
            } else {
                onSetPropertyDrvr(this, value);
            }
        })
        .onMsgEvent(HVAC_SEAT_TEMPERATURE_MSG_2, [this]() {
            removeMessage(this, HVAC_SEAT_TEMPERATURE_MSG_2);
            // 3s后根据反馈信号更新
            setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::Off);

            auto sdbValue = mappingValue(SIGNAL.getPassSeatHeatgLvlSts(), SEAT_CLIMA_OFF);

            VHALOG.d("halOnMsgEvent HVAC_SEAT_TEMPERATURE HVAC_SEAT_TEMPERATURE_MSG_2: g_heatPassReqValue:%d, sdbValue: %d", g_heatPassReqValue, sdbValue);
            if (g_heatPassReqValue != sdbValue) {
                g_heatPassReqValue = sdbValue;
                setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::On);
                setPassSeatHeat(g_heatPassReqValue);
            }
            setValue(toInt(getPassArea()), g_heatPassReqValue, false);
        })
        .onMsgEvent(HVAC_SEAT_TEMPERATURE_PASS_NB, []() {
            VHALOG.d("halOnMsgEvent HVAC_SEAT_TEMPERATURE HVAC_SEAT_TEMPERATURE_PASS_NB ");
            setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::On);
            setPassSeatHeat(SEAT_CLIMA_OFF);
        })
        .area(VehicleAreaSeat::ROW_2_LEFT)
        .initValue([]() { return SEAT_CLIMA_OFF; })
        .withStatusBySignals([this]([[maybe_unused]] const PropertyStatus& lastStatus) {
            VHALOG.d("HVAC_SEAT_TEMPERATURE ROW_2_LEFT  cc181[%d], cc13[%d], usgmod[%d], carmod[%d],  chrSt[%d], secLeAvlSts[%d]",
                SIGNAL.getcarconfig181(), SIGNAL.getcarconfig13(), SIGNAL.getVehModMngtGlbSafe1UsgModSts(), SIGNAL.getVehModMngtGlbSafe1CarModSts1(), SIGNAL.getOnBdChrgrSt(),
                SIGNAL.getSeatHeatgAvlStsRowSecLe());
            checkCountdown(this, VehicleAreaSeat::ROW_2_LEFT, mIsSecLeCounting, mSecLeStart, mSecLeEnd);
            return getSeatHeatSecLeStatus();
        },SignalRX::carconfig181,
        SignalRX::carconfig13,
        SignalRX::OnBdChrgrSt,
        SignalRX::VehModMngtGlbSafe1UsgModSts,
        SignalRX::VehModMngtGlbSafe1CarModSts1,
        SignalRX::RowSecLeODSSts,
        SignalRX::SeatHeatgLvlStsRowSecLe,
        SignalRX::SeatHeatgAvlStsRowSecLe)
        .withValueBySignals([]([[maybe_unused]] const int32_t& last) {
            if (isWaiting(HVAC_SEAT_TEMPERATURE_MSG_3)) {
                VHALOG.d("HVAC_SEAT_TEMPERATURE ROW_2_LEFT isWaiting HVAC_SEAT_TEMPERATURE_MSG_3 return.");
                return last;
            }
            sdb::SeatClimaLvl sdblvl = SIGNAL.getSeatHeatgLvlStsRowSecLe();
            auto hallvl = mappingValue(sdblvl, SEAT_CLIMA_OFF);
            g_heatSecLeReqValue = hallvl;
            VHALOG.d("HVAC_SEAT_TEMPERATURE ROW_2_LEFT value sdblvl : %d , hallvl:%d ", toInt(sdblvl), hallvl);
            return hallvl;
        }, SignalRX::SeatHeatgLvlStsRowSecLe)
        .onSetProperty([this](const int32_t& value) {
            VHALOG.d("HVAC_SEAT_TEMPERATURE ROW_2_LEFT onSetProperty value: %d", value);
            if (value != SEAT_CLIMA_OFF &&
                value != SEAT_CLIMA_LEVEL_1 &&
                value != SEAT_CLIMA_LEVEL_2 &&
                value != SEAT_CLIMA_LEVEL_3) {
                VHALOG.d("HVAC_SEAT_TEMPERATURE ROW_2_LEFT: param invalid");
                return;
            }
            if (mappingValue(SIGNAL.getSeatHeatgLvlStsRowSecLe(), SEAT_CLIMA_OFF) == value) {
                return;
            }
            clearCountdown(this, VehicleAreaSeat::ROW_2_LEFT);
            sendMessage(this, HVAC_SEAT_TEMPERATURE_MSG_3, value);
        })
        .onMsgEvent(HVAC_SEAT_TEMPERATURE_MSG_3, [this]() {
            removeMessage(this, HVAC_SEAT_TEMPERATURE_MSG_3);
            // 3s后根据反馈信号更新
            setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::Off);

            auto sdbValue = mappingValue(SIGNAL.getSeatHeatgLvlStsRowSecLe(), SEAT_CLIMA_OFF);

            VHALOG.d("halOnMsgEvent HVAC_SEAT_TEMPERATURE HVAC_SEAT_TEMPERATURE_MSG_3: g_heatSecLeReqValue:%d, sdbValue: %d", g_heatSecLeReqValue, sdbValue);
            if (g_heatSecLeReqValue != sdbValue) {
                g_heatSecLeReqValue = sdbValue;
                setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::On);
                setPassSeatHeat(g_heatSecLeReqValue);
            }
            setValue(toInt(VehicleAreaSeat::ROW_2_LEFT), g_heatSecLeReqValue, false);
        })
        .onMsgEvent(HVAC_SEAT_TEMPERATURE_SEC_LE_NB, []() {
            VHALOG.d("halOnMsgEvent HVAC_SEAT_TEMPERATURE HVAC_SEAT_TEMPERATURE_SEC_LE_NB ");
            setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::On);
            setSecLeSeatHeat(SEAT_CLIMA_OFF);
        })
        .area(VehicleAreaSeat::ROW_2_RIGHT)
        .initValue([]() { return SEAT_CLIMA_OFF; })
        .withStatusBySignals([this]([[maybe_unused]] const PropertyStatus& lastStatus) {
            VHALOG.d("HVAC_SEAT_TEMPERATURE ROW_2_RIGHT  cc181[%d], cc13[%d], usgmod[%d], carmod[%d],  chrSt[%d], secRiAvlSts[%d]",
                SIGNAL.getcarconfig181(), SIGNAL.getcarconfig13(), SIGNAL.getVehModMngtGlbSafe1UsgModSts(), SIGNAL.getVehModMngtGlbSafe1CarModSts1(), SIGNAL.getOnBdChrgrSt(),
                SIGNAL.getSeatHeatgAvlStsRowSecRi());
            checkCountdown(this, VehicleAreaSeat::ROW_2_RIGHT, mIsSecRiCounting, mSecRiStart, mSecRiEnd);
            return getSeatHeatSecRiStatus();
        },SignalRX::carconfig181,
        SignalRX::carconfig13,
        SignalRX::OnBdChrgrSt,
        SignalRX::VehModMngtGlbSafe1UsgModSts,
        SignalRX::VehModMngtGlbSafe1CarModSts1,
        SignalRX::RowSecRiODSSts,
        SignalRX::SeatHeatgLvlStsRowSecRi,
        SignalRX::SeatHeatgAvlStsRowSecRi)
        .withValueBySignals([]([[maybe_unused]] const int32_t& last) {
            if (isWaiting(HVAC_SEAT_TEMPERATURE_MSG_4)) {
                VHALOG.d("HVAC_SEAT_TEMPERATURE ROW_2_RIGHT isWaiting HVAC_SEAT_TEMPERATURE_MSG_4 return.");
                return last;
            }
            sdb::SeatClimaLvl sdblvl = SIGNAL.getSeatHeatgLvlStsRowSecRi();
            auto hallvl = mappingValue(sdblvl, SEAT_CLIMA_OFF);
            g_heatSecRiReqValue = hallvl;
            VHALOG.d("HVAC_SEAT_TEMPERATURE ROW_2_RIGHT value sdblvl : %d , hallvl:%d ", toInt(sdblvl), hallvl);
            return hallvl;
        }, SignalRX::SeatHeatgLvlStsRowSecRi)
        .onSetProperty([this](const int32_t& value) {
            VHALOG.d("HVAC_SEAT_TEMPERATURE ROW_2_RIGHT onSetProperty value: %d", value);
            if (value != SEAT_CLIMA_OFF &&
                value != SEAT_CLIMA_LEVEL_1 &&
                value != SEAT_CLIMA_LEVEL_2 &&
                value != SEAT_CLIMA_LEVEL_3) {
                VHALOG.d("HVAC_SEAT_TEMPERATURE ROW_2_RIGHT: param invalid");
                return;
            }
            if (mappingValue(SIGNAL.getSeatHeatgLvlStsRowSecRi(), SEAT_CLIMA_OFF) == value) {
                return;
            }
            clearCountdown(this, VehicleAreaSeat::ROW_2_RIGHT);
            sendMessage(this, HVAC_SEAT_TEMPERATURE_MSG_4, value);
        })
        .onMsgEvent(HVAC_SEAT_TEMPERATURE_MSG_4, [this]() {
            removeMessage(this, HVAC_SEAT_TEMPERATURE_MSG_4);
            // 3s后根据反馈信号更新
            setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::Off);

            auto sdbValue = mappingValue(SIGNAL.getSeatHeatgLvlStsRowSecRi(), SEAT_CLIMA_OFF);

            VHALOG.d("halOnMsgEvent HVAC_SEAT_TEMPERATURE HVAC_SEAT_TEMPERATURE_MSG_4: g_heatSecRiReqValue:%d, sdbValue: %d", g_heatSecRiReqValue, sdbValue);
            if (g_heatSecRiReqValue != sdbValue) {
                g_heatSecRiReqValue = sdbValue;
                setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::On);
                setPassSeatHeat(g_heatSecRiReqValue);
            }
            setValue(toInt(VehicleAreaSeat::ROW_2_RIGHT), g_heatSecRiReqValue, false);
        })
        .onMsgEvent(HVAC_SEAT_TEMPERATURE_SEC_RI_NB, []() {
            VHALOG.d("halOnMsgEvent HVAC_SEAT_TEMPERATURE HVAC_SEAT_TEMPERATURE_SEC_RI_NB ");
            setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::On);
            setSecRiSeatHeat(SEAT_CLIMA_OFF);
        });
}

void offSeatClimaAll(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, bool offDriverV,
        bool offPassV, bool offSecLeV, bool offSecRiV, bool offDriverH, bool offPassH, bool offSecLeH, bool offSecRiH) {
    VHALOG.d("HVAC_SEAT_TEMPERATURE|HVAC_SEAT_VENTILATION  offSeatClimaAll, offDriverV: %d, offPassV: %d, offSecLeV: %d,"
        "offSecRiV: %d, offDriverH: %d, offPassH: %d, offSecLeH: %d, offSecRiH: %d, mIsPassCounting: %d, mIsSecLeCounting: %d, mIsSecRiCounting: %d",
        offDriverV, offPassV, offSecLeV, offSecRiV, offDriverH, offPassH, offSecLeH, offSecRiH, mIsPassCounting, mIsSecLeCounting, mIsSecRiCounting);
    
    if (offDriverV || offPassV || offSecLeV || offSecRiV || offDriverH || offPassH || offSecLeH || offSecRiH) {
        if (offPassH) {
            clearCountdown(thisPtr, getPassArea());
            if (mIsPassCounting) {
                thisPtr->setValue(toInt(getPassArea()), SEAT_CLIMA_OFF, false);
            }
        }
        if (offSecLeH) {
            clearCountdown(thisPtr, VehicleAreaSeat::ROW_2_LEFT);
            if (mIsSecLeCounting) {
                thisPtr->setValue(toInt(VehicleAreaSeat::ROW_2_LEFT), SEAT_CLIMA_OFF, false);
            }
        }
        if (offSecRiH) {
            clearCountdown(thisPtr, VehicleAreaSeat::ROW_2_RIGHT);
            if (mIsSecRiCounting) {
                thisPtr->setValue(toInt(VehicleAreaSeat::ROW_2_RIGHT), SEAT_CLIMA_OFF, false);
            }
        }

        setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::On);
        setSeatHeat(offDriverH ? SEAT_CLIMA_OFF : NONE,
                    offPassH ? SEAT_CLIMA_OFF : NONE,
                    offSecLeH ? SEAT_CLIMA_OFF : NONE,
                    offSecRiH ? SEAT_CLIMA_OFF : NONE,
                    offDriverV ? SEAT_CLIMA_OFF : NONE,
                    offPassV ? SEAT_CLIMA_OFF : NONE,
                    offSecLeV ? SEAT_CLIMA_OFF : NONE,
                    offSecRiV ? SEAT_CLIMA_OFF : NONE);
    }
}

void checkCountdown(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, VehicleAreaSeat area, bool &isCounting,
        std::chrono::time_point<std::chrono::steady_clock> &start, std::chrono::time_point<std::chrono::steady_clock> &end) {
    if (thisPtr == nullptr) {
        VHALOG.d("HVAC_SEAT_TEMPERATURE checkCountdown this is null");
        return;
    }
    uint32_t msgIdNB = 0;
    sdb::OccptPresSt1 odsSts = sdb::OccptPresSt1::Undefd1;
    sdb::SeatClimaLvl sdblvl = sdb::SeatClimaLvl::Off;
    if (area == getPassArea()) {
        msgIdNB = HVAC_SEAT_TEMPERATURE_PASS_NB;
        odsSts = SIGNAL.getRowFrstPassODSSts();
        sdblvl = SIGNAL.getPassSeatHeatgLvlSts();
    } else if (area == VehicleAreaSeat::ROW_2_LEFT) {
        msgIdNB = HVAC_SEAT_TEMPERATURE_SEC_LE_NB;
        odsSts = SIGNAL.getRowSecLeODSSts();
        sdblvl = SIGNAL.getSeatHeatgLvlStsRowSecLe();
    } else {
        msgIdNB = HVAC_SEAT_TEMPERATURE_SEC_RI_NB;
        odsSts = SIGNAL.getRowSecRiODSSts();
        sdblvl = SIGNAL.getSeatHeatgLvlStsRowSecRi();
    }

    int32_t nobdLcfg = lcfg::LocalConfig::getInstance().getInt<int32_t>(lcfg::LCFG_CountdownofHeatingNobody);
    int32_t curHalValue = thisPtr->getPropertyValue<int32_t>(
                static_cast<int32_t>(VehicleProperty::HVAC_SEAT_TEMPERATURE),
                static_cast<int32_t>(area));
    VHALOG.d("HVAC_SEAT_TEMPERATURE AREA checkCountdown : %d, msgIdNB: %d, odsSts: %d, sdblvl: %d, nobdLcfg: %d, curHalValue: %d",
            area, msgIdNB, odsSts, sdblvl, nobdLcfg, curHalValue);
    if (!isCounting && sdblvl !=  sdb::SeatClimaLvl::Off && odsSts == sdb::OccptPresSt1::OccptNotPrsnt) {
         VHALOG.d("HVAC_SEAT_TEMPERATURE AREA checkCountdown : start countdown");
        isCounting = true;
        start = std::chrono::steady_clock::now();
        thisPtr->sendMsg(msgIdNB, nobdLcfg * 1000);
    } else if (isCounting && curHalValue !=  SEAT_CLIMA_OFF && odsSts == sdb::OccptPresSt1::OccptPrsnt) {
        end = std::chrono::steady_clock::now();
        std::chrono::duration<float> duration = end - start;
        VHALOG.d("HVAC_SEAT_TEMPERATURE AREA: %d, duration: %f", area, duration.count());
        if (duration.count() < nobdLcfg) {
            clearCountdown(thisPtr, area);
        }
    }
}

void clearCountdown(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, VehicleAreaSeat area) {
    if (area == getPassArea()) {
        mIsPassCounting = false;
        thisPtr->removeMsg(HVAC_SEAT_TEMPERATURE_PASS_NB);
    } else if (area == VehicleAreaSeat::ROW_2_LEFT) {
        mIsSecLeCounting = false;
        thisPtr->removeMsg(HVAC_SEAT_TEMPERATURE_SEC_LE_NB);
    } else {
        mIsSecRiCounting = false;
        thisPtr->removeMsg(HVAC_SEAT_TEMPERATURE_SEC_RI_NB);
    }
}

PropertyStatus withStatusBySignalsDrvr(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr) {
    VHALOG.d("HVAC_SEAT_TEMPERATURE DRVR  cc180[%d], cc13[%d], usgmod[%d], carmod[%d],  chrSt[%d], drvrAvlSts[%d]",
            SIGNAL.getcarconfig180(), SIGNAL.getcarconfig13(), SIGNAL.getVehModMngtGlbSafe1UsgModSts(), SIGNAL.getVehModMngtGlbSafe1CarModSts1(), SIGNAL.getOnBdChrgrSt(),
            SIGNAL.getDrvrSeatHeatgAvlSts());
    auto usgmod = SIGNAL.getVehModMngtGlbSafe1UsgModSts();
    bool isCnvincToOther = (lastUsgMode == sdb::UsgModSts1::UsgModCnvinc) && (usgmod != sdb::UsgModSts1::UsgModCnvinc);
    bool isDriverToOther = (lastUsgMode == sdb::UsgModSts1::UsgModDrvg) && (usgmod != sdb::UsgModSts1::UsgModDrvg);
    bool isOtherToDriver = (lastUsgMode != sdb::UsgModSts1::UsgModDrvg) && (usgmod == sdb::UsgModSts1::UsgModDrvg);
    lastUsgMode = usgmod;

    auto valueDriver = thisPtr->getPropertyValue<int32_t>(
        static_cast<int32_t>(VehicleProperty::HVAC_SEAT_TEMPERATURE),
        static_cast<int32_t>(getDrvrArea()));
    auto valuePass = thisPtr->getPropertyValue<int32_t>(
        static_cast<int32_t>(VehicleProperty::HVAC_SEAT_TEMPERATURE),
        static_cast<int32_t>(getPassArea()));
    auto ambTRawQly = (int32_t)SIGNAL.getAmbTRawQly();
    auto ambTRawAmbTVal = (float)SIGNAL.getAmbTRawAmbTVal();
    VHALOG.d("HVAC_SEAT_TEMPERATURE DRVR  valueDriver[%d], valuePass[%d], ambTRawQly[%d], ambTRawAmbTVal[%f], isDriverToOther[%d], isOtherToDriver[%d]",
            valueDriver, valuePass, ambTRawQly, ambTRawAmbTVal, isDriverToOther, isOtherToDriver);
    if (isDriverToOther) {                          // 触发检测座椅加热自启动数据保存逻辑
        if (valueDriver != SEAT_CLIMA_OFF) {  // 主驾驶座椅加热档位当前为打开，且触发驾驶到不驾驶
            bool autoSeatHeatFlagDriver = (ambTRawQly == toInt(sdb::GenQf1::AccurData));
            if (autoSeatHeatFlagDriver) {
                thisPtr->getDID()->setInt32(DID_DRVR_SEAT_HEATG_LVL_STS, valueDriver);
                thisPtr->getDID()->setFloat(DID_DRVR_AMB_T_RAW_AMB_T_VAL, ambTRawAmbTVal);
            }
            VHALOG.d("HVAC_SEAT_TEMPERATURE DRVR SAVE autoSeatHeatFlagDriver:%d", autoSeatHeatFlagDriver);
            thisPtr->getDID()->setBool(DID_DRVR_AUTO_SEAT_HEAT_FLAG, autoSeatHeatFlagDriver);
        } else {
            thisPtr->getDID()->setBool(DID_DRVR_AUTO_SEAT_HEAT_FLAG, false);
        }

        if (valuePass != SEAT_CLIMA_OFF) {  // 副驾驶座椅加热档位当前为打开，且触发驾驶到不驾驶
            bool autoSeatHeatFlagPass = (ambTRawQly == toInt(sdb::GenQf1::AccurData));
            if (autoSeatHeatFlagPass) {
                thisPtr->getDID()->setInt32(DID_PASS_SEAT_HEATG_LVL_STS, valuePass);
                thisPtr->getDID()->setFloat(DID_PASS_AMB_T_RAW_AMB_T_VAL, ambTRawAmbTVal);
            }
            VHALOG.d("HVAC_SEAT_TEMPERATURE DRVR SAVE DID autoSeatHeatFlagPass:%d", autoSeatHeatFlagPass);
            thisPtr->getDID()->setBool(DID_PASS_AUTO_SEAT_HEAT_FLAG, autoSeatHeatFlagPass);
        } else {
            thisPtr->getDID()->setBool(DID_PASS_AUTO_SEAT_HEAT_FLAG, false);
        }
    }

    if (isCnvincToOther) {
        VHALOG.d("HVAC_SEAT_TEMPERATURE isCnvincToOther setCB_VFC_SeatClimaForHmiCenPDC off ");
        setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::Off);
    }

    PropertyStatus driverStatusV = getSeatVentDriverStatus();
    PropertyStatus passStatusV = getSeatVentPassStatus();
    PropertyStatus secLeStatusV = getSeatVentSecLeStatus();
    PropertyStatus secRiStatusV = getSeatVentSecRiStatus();

    PropertyStatus driverStatusH = getSeatHeatDriverStatus();
    PropertyStatus passStatusH = getSeatHeatPassStatus();
    PropertyStatus secLeStatusH = getSeatHeatSecLeStatus();
    PropertyStatus secRiStatusH = getSeatHeatSecRiStatus();

    if (!hasSendTmr && (driverStatusH == PropertyStatus::Active || passStatusH == PropertyStatus::Active
            || secLeStatusH == PropertyStatus::Active || secRiStatusH == PropertyStatus::Active)) {
        // 发送固定的加热时长信号
        sendSeatHeatTmr();
        hasSendTmr = true;
    }

    if (isOtherToDriver) {  // 触发检测座椅加热自启动逻辑
        bool needResetDriver = false;
        bool needResetPass = false;
        if (driverStatusH == PropertyStatus::Active) {
            VHALOG.d("HVAC_SEAT_TEMPERATURE DRVR GETDID DIDDrvrlvl %d, autoSeatHeatFlagDriver:%d, curhalValue:%d, ambTRawAmbTVal:%f, DIDAmbTRawAmbTValDriver:%f",
                    thisPtr->getDID()->getInt32(DID_DRVR_SEAT_HEATG_LVL_STS, 0), thisPtr->getDID()->getBool(DID_DRVR_AUTO_SEAT_HEAT_FLAG, false),
                    valueDriver, ambTRawAmbTVal, thisPtr->getDID()->getFloat(DID_DRVR_AMB_T_RAW_AMB_T_VAL, 0.0f));

            if (thisPtr->getDID()->getBool(DID_DRVR_AUTO_SEAT_HEAT_FLAG, false) &&
                valueDriver == SEAT_CLIMA_OFF &&
                ambTRawQly == toInt(sdb::GenQf1::AccurData) && ambTRawAmbTVal - thisPtr->getDID()->getFloat(DID_DRVR_AMB_T_RAW_AMB_T_VAL, 0) <= 10) {  // 主驾驶恢复加热状态的条件
                thisPtr->getDID()->setBool(DID_DRVR_AUTO_SEAT_HEAT_FLAG, false);
                needResetDriver = true;
                g_heatDrvrReqValue = thisPtr->getDID()->getInt32(DID_DRVR_SEAT_HEATG_LVL_STS, 0);
            }
        }

        if (passStatusH == PropertyStatus::Active) {
            VHALOG.d("HVAC_SEAT_TEMPERATURE DRVR GETDID PassSeatHeatgLvlSts %d, autoSeatHeatFlagPass:%d, curhalValue:%d, ambTRawAmbTVal:%f, DIDAmbTRawAmbTValPass:%f",
                    thisPtr->getDID()->getInt32(DID_PASS_SEAT_HEATG_LVL_STS, 0), thisPtr->getDID()->getBool(DID_PASS_AUTO_SEAT_HEAT_FLAG, false),
                    valuePass, ambTRawAmbTVal, thisPtr->getDID()->getFloat(DID_PASS_AMB_T_RAW_AMB_T_VAL, 0.0f));
            if (thisPtr->getDID()->getBool(DID_PASS_AUTO_SEAT_HEAT_FLAG, false) &&
                valuePass == SEAT_CLIMA_OFF &&
                ambTRawQly == toInt(sdb::GenQf1::AccurData) && ambTRawAmbTVal - thisPtr->getDID()->getFloat(DID_PASS_AMB_T_RAW_AMB_T_VAL, 0) <= 10) {  // 副驾驶恢复加热状态的条件
                thisPtr->getDID()->setBool(DID_PASS_AUTO_SEAT_HEAT_FLAG, false);
                needResetPass = true;
                g_heatPassReqValue = thisPtr->getDID()->getInt32(DID_PASS_SEAT_HEATG_LVL_STS, 0);
            }
        }
        if (needResetDriver || needResetPass) {
            setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::On);
            VHALOG.d("HVAC_SEAT_TEMPERATURE  DRVR resetSeatHeat needResetDriver: %d, needResetPass %d", needResetDriver, needResetPass);
            setSeatHeat(needResetDriver ? thisPtr->getDID()->getInt32(DID_DRVR_SEAT_HEATG_LVL_STS, 0) : NONE,
                        needResetPass ? thisPtr->getDID()->getInt32(DID_PASS_SEAT_HEATG_LVL_STS, 0) : NONE,
                        NONE, NONE, NONE, NONE, NONE, NONE);
        }
    }

    bool offDriverV = (driverStatusV == PropertyStatus::NotActive || driverStatusV == PropertyStatus::NotAvailable);
    bool offPassV = (passStatusV == PropertyStatus::NotActive || passStatusV == PropertyStatus::NotAvailable);
    bool offSecLeV = (secLeStatusV == PropertyStatus::NotActive || secLeStatusV == PropertyStatus::NotAvailable);
    bool offSecRiV = (secRiStatusV == PropertyStatus::NotActive || secRiStatusV == PropertyStatus::NotAvailable);

    bool offDriverH = (driverStatusH == PropertyStatus::NotActive || driverStatusH == PropertyStatus::NotAvailable);
    bool offPassH = (passStatusH == PropertyStatus::NotActive || passStatusH == PropertyStatus::NotAvailable);
    bool offSecLeH = (secLeStatusH == PropertyStatus::NotActive || secLeStatusH == PropertyStatus::NotAvailable);
    bool offSecRiH = (secRiStatusH == PropertyStatus::NotActive || secRiStatusH == PropertyStatus::NotAvailable);

    // VMM不满足时，将座椅通风和座椅加热设置为OFF
    offSeatClimaAll(thisPtr, offDriverV, offPassV, offSecLeV, offSecRiV, offDriverH, offPassH, offSecLeH, offSecRiH);

    return driverStatusH;
}

PropertyStatus withStatusBySignalsPass(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr) {
    VHALOG.d("HVAC_SEAT_TEMPERATURE PASS  cc180[%d], cc13[%d], usgmod[%d], carmod[%d], chrSt[%d], passAvlSts[%d]",
        SIGNAL.getcarconfig180(), SIGNAL.getcarconfig13(), SIGNAL.getVehModMngtGlbSafe1UsgModSts(), SIGNAL.getVehModMngtGlbSafe1CarModSts1(),
        SIGNAL.getOnBdChrgrSt(), SIGNAL.getPassSeatHeatgAvlSts());
    checkCountdown(thisPtr, getPassArea(), mIsPassCounting, mPassStart, mPassEnd);
    return getSeatHeatPassStatus();
}

int32_t withValueBySignalsDrvr(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, const int32_t& last) {
    if (isWaiting(HVAC_SEAT_TEMPERATURE_MSG_1)) {
        VHALOG.d("HVAC_SEAT_TEMPERATURE DRVR isWaiting HVAC_SEAT_TEMPERATURE_MSG_1 return.");
        return last;
    }
    sdb::SeatClimaLvl sdblvl = SIGNAL.getDrvrSeatHeatgLvlSts();
    auto hallvl = mappingValue(sdblvl, SEAT_CLIMA_OFF);
    g_heatDrvrReqValue = hallvl;
    VHALOG.d("HVAC_SEAT_TEMPERATURE DRVR value sdblvl : %d , hallvl:%d ", toInt(sdblvl), hallvl);
    return hallvl;
}

int32_t withValueBySignalsPass(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, const int32_t& last) {
    if (isWaiting(HVAC_SEAT_TEMPERATURE_MSG_2)) {
        VHALOG.d("HVAC_SEAT_TEMPERATURE PASS isWaiting HVAC_SEAT_TEMPERATURE_MSG_2 return.");
        return last;
    }
    sdb::SeatClimaLvl sdblvl = SIGNAL.getPassSeatHeatgLvlSts();
    auto hallvl = mappingValue(sdblvl, SEAT_CLIMA_OFF);
    g_heatPassReqValue = hallvl;
    VHALOG.d("HVAC_SEAT_TEMPERATURE PASS value sdblvl : %d , hallvl:%d ", toInt(sdblvl), hallvl);
    return hallvl;
}

void onSetPropertyDrvr(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, const int32_t& value) {
   VHALOG.d("HVAC_SEAT_TEMPERATURE DRVR onSetProperty value: %d", value);
    if (value != SEAT_CLIMA_OFF &&
        value != SEAT_CLIMA_LEVEL_1 &&
        value != SEAT_CLIMA_LEVEL_2 &&
        value != SEAT_CLIMA_LEVEL_3) {
        VHALOG.d("HVAC_SEAT_TEMPERATURE DRVR: param invalid");
        return;
    }
    if (mappingValue(SIGNAL.getDrvrSeatHeatgLvlSts(), SEAT_CLIMA_OFF) == value) {
        return;
    }

    sendMessage(thisPtr, HVAC_SEAT_TEMPERATURE_MSG_1, value);
}

void onSetPropertyPass(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, const int32_t& value) {
    VHALOG.d("halOnSetProperty HVAC_SEAT_TEMPERATURE PASS value: %d", value);
    if (value != SEAT_CLIMA_OFF &&
        value != SEAT_CLIMA_LEVEL_1 &&
        value != SEAT_CLIMA_LEVEL_2 &&
        value != SEAT_CLIMA_LEVEL_3) {
        VHALOG.d("HVAC_SEAT_TEMPERATURE PASS: param invalid");
        return;
    }
    if (mappingValue(SIGNAL.getPassSeatHeatgLvlSts(), SEAT_CLIMA_OFF) == value) {
        return;
    }
    clearCountdown(thisPtr, getPassArea());
    sendMessage(thisPtr, HVAC_SEAT_TEMPERATURE_MSG_2, value);
}

static void removeMessage(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, uint32_t msgId) {
    switch (msgId)
    {
    case HVAC_SEAT_TEMPERATURE_MSG_1:
        mIsWaitingMsg1 = false;
        break;
    case HVAC_SEAT_TEMPERATURE_MSG_2:
        mIsWaitingMsg2 = false;
        break;
    case HVAC_SEAT_TEMPERATURE_MSG_3:
        mIsWaitingMsg3 = false;
        break;
    case HVAC_SEAT_TEMPERATURE_MSG_4:
        mIsWaitingMsg4 = false;
        break;

    }
    thisPtr->removeMsg(msgId);
}

static void sendMessage(ecarx::vhal::core::property::impl::VehiclePropertyHVAC_SEAT_TEMPERATURE* thisPtr, uint32_t msgId, int32_t value) {
    setCB_VFC_SeatClimaForHmiCenPDC(sdb::OnOff1::On);
    switch (msgId)
    {
    case HVAC_SEAT_TEMPERATURE_MSG_1:
        mIsWaitingMsg1 = true;
        g_heatDrvrReqValue = value;
        setDriverSeatHeat(value);
        break;
    case HVAC_SEAT_TEMPERATURE_MSG_2:
        mIsWaitingMsg2 = true;
        g_heatPassReqValue = value;
        setPassSeatHeat(value);
        break;
    case HVAC_SEAT_TEMPERATURE_MSG_3:
        mIsWaitingMsg3 = true;
        g_heatSecLeReqValue = value;
        setSecLeSeatHeat(value);
        break;
    case HVAC_SEAT_TEMPERATURE_MSG_4:
        mIsWaitingMsg4 = true;
        g_heatSecRiReqValue = value;
        setSecRiSeatHeat(value);
        break;
    
    }
    thisPtr->removeMsg(msgId);
    thisPtr->sendMsg(msgId, HVAC_DELAY);
}